import os
import pathlib
import time

import allure
from appium.options.common import AppiumOptions
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.webdriver.webdriver import WebDriver
from selenium.common import NoSuchElementException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

from ..utils.log_util import logger


class Base:
    __IMPLICITLY_WAIT_TIME = 10
    __APP_PACKAGE = "com.tencent.wework"

    def __init__(self, driver: WebDriver = None):
        if driver is None:
            self.driver_connect()
        else:
            self.driver = driver

    def driver_connect(self):
        caps = {}
        # 设置 app 安装平台
        caps["appium:platformName"] = "Android"
        # 设置 app 安装平台的版本
        # caps["appium:platformVersion"] = "6"
        # 设备的名字
        caps["appium:deviceName"] = "RPG0218A23005608"
        # 设置 app 的包名
        caps["appium:appPackage"] = "com.tencent.wework"
        # 设置 app 启动页
        caps["appium:appActivity"] = ".launch.LaunchSplashActivity"
        # 不清空缓存
        caps["appium:noReset"] = True
        # 实例化 appiumOptions 对象
        options = AppiumOptions().load_capabilities(caps)
        os.system('start cmd /k appium')
        # 连接 appium server
        self.driver = webdriver.Remote("http://localhost:4723/wd/hub", options=options)
        # 设置全局的隐式等待
        self.driver.implicitly_wait(self.__IMPLICITLY_WAIT_TIME)

    def swipe_window(self):
        '''
        滑动界面
        '''
        # 滑动操作
        # 获取设备的尺寸
        size = self.driver.get_window_size()
        # {"width": xx, "height": xx}
        print(f"设备尺寸为 {size}")
        width = size.get("width")
        height = size.get('height')
        # # 获取滑动操作的坐标值
        start_x = width / 2
        start_y = height * 0.8
        end_x = start_x
        end_y = height * 0.2
        # swipe(起始x坐标，起始y坐标，结束x坐标，结束y坐标，滑动时间（单位毫秒）)
        self.driver.swipe(start_x, start_y, end_x, end_y, 2000)

    def swipe_find(self, text, max_num=5):
        '''
        滑动查找
        通过文本来查找元素，如果没有找到元素，就滑动，
        如果找到了，就返回元素
        '''
        # 为了滑动操作更快速，不用等待隐式等待设置的时间
        logger.info(f"滑动查找元素,元素文本内容({text})")
        self.driver.implicitly_wait(1)
        for num in range(max_num):
            try:
                # 正常通过文本查找元素
                ele = self.driver.find_element(AppiumBy.XPATH, f"//*[@text='{text}']")
                print("找到元素")
                # 能找到则把隐式等待恢复原来的时间
                self.driver.implicitly_wait(10)
                # 返回找到的元素对象
                return ele
            except Exception:
                # 当查找元素发生异常时
                print(f"没有找到元素，开始滑动")
                print(f"滑动第{num + 1}次")
                # 滑动操作
                self.swipe_window()
        # 把隐式等待恢复原来的时间
        self.driver.implicitly_wait(self.__IMPLICITLY_WAIT_TIME)
        # 抛出找不到元素的异常
        raise NoSuchElementException(f"滑动之后，未找到 {text} 元素")

    def screenshot(self):
        '''
        截图
        :param path: 截图保存路径
        '''
        root_path = pathlib.Path(__file__).parent.parent
        cur_time = time.strftime("%Y-%m-%d-%H-%M-%S")
        file_path = cur_time + ".png"
        dir_path = root_path / 'screenshot'
        # 资源目录如果不存在则新创建一个
        if not os.path.isdir(dir_path):
            os.mkdir(dir_path)
        # 截图保存路径
        source_path = dir_path / file_path
        # 截图
        self.driver.save_screenshot(source_path)
        # 返回保存图片的路径
        return source_path

    def find_ele(self, by, value=None):
        if value is None:
            logger.info(f'定位单个元素,定位方式为{by}')
            ele = self.driver.find_element(*by)
        else:
            logger.info(f'定位单个元素,定位方式为{by},定位表达式{value}')
            ele = self.driver.find_element(by, value)
        return ele

    def find_eles(self, by, value=None):
        if value is None:
            logger.info(f'定位多个元素,定位方式为{by}')
            eles = self.driver.find_elements(*by)
        else:
            logger.info(f'定位单个元素,定位方式为{by},定位表达式{value}')
            eles = self.driver.find_elements(by, value)
        return eles

    def find_ele_wait_until_located(self, by, value=None, timeout=10):
        if value is None:
            logger.info(f'显示等待单个元素出现,定位方式为{by}')
            ele = WebDriverWait(self.driver, timeout).until(EC.visibility_of_element_located(by))
        else:
            tmp = (by, value)
            logger.info(f'显示等待单个元素出现,定位方式为{tmp}')
            ele = WebDriverWait(self.driver, timeout).until(EC.visibility_of_element_located(tmp))

        return ele

    def find_eles_wait_until_located(self, by, value=None, timeout=10):
        if value is None:
            logger.info(f'显示等待多个元素出现,定位方式为{by}')
            eles = WebDriverWait(self.driver, timeout).until(EC.visibility_of_element_located(by))
        else:
            tmp = (by, value)
            logger.info(f'显示等待多个元素出现,定位方式为{tmp}')
            eles = WebDriverWait(self.driver, timeout).until(EC.visibility_of_element_located(tmp))

        return eles

    def find_ele_wait_until_not_located(self, by, value=None, timeout=10):
        if value is None:
            logger.info(f'显示等待单个元素消失,定位方式为{by}')
            ele = WebDriverWait(self.driver, timeout).until(EC.visibility_of_element_located(by))
        else:
            tmp = (by, value)
            logger.info(f'显示等待单个元素消失,定位方式为{by}')
            ele = WebDriverWait(self.driver, timeout).until(EC.visibility_of_element_located(tmp))

        return ele

    def find_eles_wait_until_not_located(self, by, value=None, timeout=10):
        if value is None:
            logger.info(f'显示等待多个元素消失,定位方式为{by}')
            eles = WebDriverWait(self.driver, timeout).until_not(EC.visibility_of_element_located(by))
        else:
            tmp = (by, value)
            logger.info(f'显示等待多个元素消失,定位方式为{by}')
            eles = WebDriverWait(self.driver, timeout).until_not(EC.visibility_of_element_located(tmp))

        return eles

    def return_main(self):
        logger.info("返回至桌面并将对应APP激活。。。。")
        for i in range(0, 5):
            self.back()
        self.driver.activate_app(self.__APP_PACKAGE)

    def quit(self):
        logger.info("关闭driver")
        self.driver.quit()

    def back(self):
        self.driver.back()
